package contegor.scire.core.queries;

import java.util.Collections;
import java.util.List;

import contegor.scire.core.Concept;
import contegor.scire.core.Connectable;
import contegor.scire.core.Container;
import contegor.scire.core.Id;
import contegor.scire.core.InfiniteSingletonList;
import contegor.scire.core.Link;
import contegor.scire.core.ReturnPoint;
import contegor.scire.core.ReturnPointAdapter;
import contegor.scire.core.TaskId;
import contegor.scire.core.Version;

/**
 * Given {@link Query}s that return {@link Concept}s, this one returns the {@link Link}s who's sources are 
 * those {@link Concept}s.
 *
 * @version $Revision$
 * @author  Héctor Cirbián Pousa ($Author$)
 */
@Version("$Id$")
public class GetLinksFromSources<T extends Connectable> extends QueryWithDependencies<T, Link> {
  private static final long serialVersionUID = -4817714642070057161L;

  private ReturnPoint<T> dependenciesReturnPoint = new ReturnPointAdapter<T>() {
    public <U extends T> void manage(TaskId taskId, U result) {
      returnPoint.manage(taskId, result.getLinks().values());
      // FIXME: Container's Links are also Concept Links but it's not accessible from here
      // Container's Links as Concept Links mechanism needs some more thinking.
    }
    public void manage(TaskId taskId, Exception exception) {
      returnPoint.manage(taskId, exception);
    }
  }; 
 
  /**
   * Constructor for {@link GetLinksFromSources} with only one dependency. The target container where
   * <code>this</code> will be processed will be the same that the one of the dependency.
   * 
   * @param dependency {@link Query} in which depends this one.
   */
  public GetLinksFromSources(Query<T> dependency) {
    super(dependency);
  }

  /**
   * Constructor for {@link GetLinksFromSources} with more than one dependency.
   * 
   * @param targetContainerId {@link Id} of the {@link Container} where this {@link Query} will be processed.
   * @param dependency {@link Query} in which depends this one.
   */
  public GetLinksFromSources(Id targetContainerId, Query<T> ... dependencies) {
    super(targetContainerId, dependencies);
  }

  public void process(Container container) {}

  @Override
  public List<? extends ReturnPoint<T>> getDependenciesReturnPoints() {
    if (this.dependencies == null)
      return Collections.emptyList();
    return new InfiniteSingletonList<ReturnPoint<T>>(dependenciesReturnPoint, dependencies.size());
  }

}